<template>
    <a-form :model="form" ref="formRef" :rules="formRules" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
        <a-form-item :label="$t('upperComputer.menuButton.menuName')" name="menuCode">
            <a-tree-select allow-clear v-model:value="form.menuCode" treeNodeFilterProp="title" show-search
                :tree-data="treeData" :field-names="{
                        children: 'childrens',
                        label: 'displayName',
                        key: 'id',
                        value: 'code',
                    }" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menuButton.code')" name="code">
            <a-input v-model:value="form.code" :maxlength="50" :disabled="form.id ? true : false" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menuButton.displayName')" name="displayName">
            <a-input v-model:value="form.displayName" :maxlength="50" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.sort')" name="sort">
            <a-input-number v-model:value="form.sort" :min="1" :precision="0" style="width: 100%" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menu.icon')" name="icon">
            <a-select v-model:value="form.icon" allow-clear show-search>
                <a-select-option v-for="(item, index) in iconNames" :key="index" :value="item">
                    {{ item }}&nbsp;
                    <menu-icon :iconName="item" />
                </a-select-option>
            </a-select>
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menuButton.isActive')" name="isActive">
            <a-switch v-model:checked="form.isActive" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menuButton.isSplit')" name="isSplit">
            <a-switch v-model:checked="form.isSplit" />
        </a-form-item>
        <a-form-item :label="$t('upperComputer.menuButton.description')" name="description">
            <a-textarea v-model:value="form.description" autoSize :maxlength="255" showCount />
        </a-form-item>
    </a-form>
</template>

<script setup lang='ts'>
import i18n from '@/i18n';
import MenuIcon from '@/components/icon/index.vue';
import { IconNames } from '@/components/icon';
import { type TreeSelectProps, type FormInstance, message } from 'ant-design-vue';
import type { BaseOptionType } from 'ant-design-vue/lib/select';
import { type Ref, ref, onMounted } from 'vue';
import { MenuButtonDto } from '@/models/menu-button';
import type { Rule } from 'ant-design-vue/lib/form';
import { getMBMenusApi, getMenuButtonApi, postMenuButtonApi, putMenuButtonApi } from '@/services/menu-button';

const props = defineProps<{ id: number }>();
defineExpose({ ok });

const iconNames: Array<string> = IconNames;
const treeData: Ref<BaseOptionType | undefined> = ref<TreeSelectProps['treeData']>();
const form: Ref<MenuButtonDto> = ref<MenuButtonDto>(new MenuButtonDto);
const formRef: Ref<FormInstance | undefined> = ref<FormInstance>();
const formRules: Record<string, Rule[]> = {
    menuCode: [
        {
            required: true,
            message: i18n.global.t('upperComputer.menuButton.required.menu'),
            trigger: 'blur'
        }
    ],
    sort: [
        {
            required: true,
            type: 'number',
            message: i18n.global.t('upperComputer.menuButton.required.sort'),
            trigger: 'blur'
        }
    ],
    code: [
        { required: true, trigger: 'blur', validator: codeValidator }
    ],
    displayName: [
        {
            required: true,
            max: 50,
            message: i18n.global.t('upperComputer.menuButton.required.botton'),
            trigger: 'blur'
        }
    ]
};

/**
 * code的正则验证
 * @param rule 
 * @param value 
 * @param callback 
 */
function codeValidator(rule: Rule, value: string, callback: Function): Promise<void> {
    const reg: RegExp = /^[A-Z][a-zA-Z]{1,49}$/;
    if (reg.test(value)) {
        return Promise.resolve();
    }
    return Promise.reject(i18n.global.t('upperComputer.menuButton.required.code'));
}

onMounted(() => {
    getTreeData();
    getForm();
});

async function getTreeData(): Promise<void> {
    treeData.value = await getMBMenusApi();
}

async function getForm(): Promise<void> {
    if (props.id) {
        form.value = await getMenuButtonApi(props.id);
    }
}

async function ok(): Promise<boolean> {
    try {
        await formRef.value?.validate();
        if (props.id) {
            await putMenuButtonApi(form.value);
        } else {
            await postMenuButtonApi(form.value);
        }
        message.success(i18n.global.t('common.' + (props.id ? 'editSuccess' : 'addSuccess')));
        return true;
    } catch {
        return false;
    }
}
</script>